"""
安装第三方模块
pip 是python的包管理工具
pip list 查看当前安装的所有包
pip install 包名   安装
pip show 包名      查看包信息
pip uninstall 包名 卸载包
pip install pygame
"""
import random

import pygame.sprite

# import pygame
#
# # 1. 初始化
# pygame.init()
# # 2. 构建用于显示的窗体 surface
# screen = pygame.display.set_mode(size=(800, 600))
#
# # 3. 填充 Surface   Rect
# bg_color = pygame.color.Color(125, 125, 125)
# bg_rect = pygame.rect.Rect(0, 0, 800, 600)
#
# # 5. 创建一个面
# center_sufarce = pygame.surface.Surface((400, 300))
# center_color = pygame.color.Color(125, 0, 0)
# center_rect = pygame.rect.Rect(0, 0, 400, 300)
#
# pos_y = -300
#
# while True:
#     # # 3. 事件处理
#     for event in pygame.event.get():
#         # 处理退出事件
#         if event.type == pygame.QUIT:
#             pygame.quit()
#             exit()
#
#     pos_y += 1
#     if pos_y == 600:
#         pos_y = -300
#
#     # 填充屏幕
#     screen.fill(bg_color, bg_rect)
#     # 填充矩形
#     center_sufarce.fill(center_color, center_rect)
#
#     # 6. 将目标surface 显示到目标区域
#     screen.blit(center_sufarce, (200, pos_y))
#
#     # 4. 更新绘制
#     pygame.display.flip()


# import pygame
# import time
#
# # 1. 初始化
# pygame.init()
# # 2. 构建用于显示的窗体 surface
# screen = pygame.display.set_mode(size=(800, 600))
#
# # 7. 标题
# pygame.display.set_caption("pygame开发")
# icon_surface = pygame.image.load("./image/favicon.ico")
# pygame.display.set_icon(icon_surface)
#
# # 3. 填充 Surface   Rect
# bg_color = pygame.color.Color(125, 125, 125)
# bg_rect = pygame.rect.Rect(0, 0, 800, 600)
#
# # 5. 创建一个面
# center_sufarce = pygame.surface.Surface((400, 300))
# center_color = pygame.color.Color(125, 0, 0)
# center_rect = pygame.rect.Rect(0, 0, 400, 300)
#
# # 9.  绘制背景图
# bg_surface = pygame.image.load("./image/bg.png")
#
#
# pos_y = -300
#
# pos_x = 50
#
# clock = pygame.time.Clock()
#
# while True:
#     #  设置帧率
#     clock.tick(20)
#
#     # # 3. 事件处理
#     for event in pygame.event.get():
#         # 处理退出事件
#         if event.type == pygame.QUIT:
#             pygame.quit()
#             exit()
#
#         # 处理键盘事件
#         if event.type == pygame.KEYUP:
#             if event.key == pygame.K_SPACE:
#                 print(f"开火")
#
#     # 获取按键是否按下状态
#     key_pressed = pygame.key.get_pressed()
#     if key_pressed[pygame.K_LEFT]:
#         pos_x -= 10
#         if pos_x <= 50:
#             pos_x = 50
#     if key_pressed[pygame.K_RIGHT]:
#         pos_x += 10
#         if pos_x >= 350:
#             pos_x = 350
#
#
#
#     pos_y += 1
#     if pos_y == 600:
#         pos_y = -300
#
#     # pos_x += 1
#     # if pos_x == 400:
#     #     pos_x = -50
#
#     # 填充屏幕
#     screen.fill(bg_color, bg_rect)
#
#     # 填充背景
#     screen.blit(bg_surface, (0, 0))
#
#     # 填充矩形
#     center_sufarce.fill(center_color, center_rect)
#     # 面上画圆
#     pygame.draw.circle(center_sufarce, (0, 255, 0), (pos_x, 250), 50)
#
#
#     # 6. 将目标surface 显示到目标区域
#     screen.blit(center_sufarce, (200, pos_y))
#
#     # 4. 更新绘制
#     pygame.display.flip()


"""
精灵： 任何一个游戏元素都可以理解为一个精灵 Sprite 
pygame.sprite.Sprite()  游戏元素精灵
pygame.sprite.Group()  精灵组（存放多个精灵）
可以将一个精灵组内所有内容绘制到一个面
通过更新精灵组来更新每一个精灵
"""

#
# class HeroSprite(pygame.sprite.Sprite):
#     def __init__(self,speed=10):
#         super().__init__()
#         self.image = pygame.surface.Surface((50,50))
#         self.image.fill("red")
#         self.rect = self.image.get_rect()
#         self.rect.center = (400, 300)
#         self.speed = speed
#
#     def update(self):
#         key_pressed = pygame.key.get_pressed()
#         if key_pressed[pygame.K_LEFT]:
#             self.rect.left -= self.speed
#             if self.rect.left <= 0:
#                 self.rect.left = 0
#
#         if key_pressed[pygame.K_RIGHT]:
#             self.rect.right += self.speed
#             if self.rect.right >= 800:
#                 self.rect.right = 800
#
#
#
#
# class BgSprite(pygame.sprite.Sprite):
#     def __init__(self, image_name, top, speed=5):
#         # 必须调用父类的初始化
#         super().__init__()
#         # image 与 rect 必须初始化
#         self.image = pygame.image.load(image_name)
#         self.rect = self.image.get_rect()
#
#         # 设置初始位置
#         self.rect.top = top
#         self.speed = speed
#
#     def update(self):
#         # 通过更新矩形的数据 来移动矩形
#         self.rect.top += self.speed
#         if self.rect.top >= 600:
#             self.rect.top = -600
#
#
# class Game:
#     def __init__(self):
#         pygame.init()
#         self.screen = pygame.display.set_mode(size=(800, 600))
#         self.init_title_logo()
#
#         # 创建背景精灵组 将两个精灵实例加入背景精灵组
#         self.bg_group = pygame.sprite.Group()
#
#         self.bg = BgSprite("./image/bg.png", 0)
#         self.bg2 = BgSprite("./image/bg2.jpeg", -600)
#         self.bg.add(self.bg_group)
#         self.bg2.add(self.bg_group)
#
#         self.hero_group = pygame.sprite.Group()
#         self.hero = HeroSprite()
#         self.hero.add(self.hero_group)
#
#
#         self.clock = pygame.time.Clock()
#
#     def init_title_logo(self):
#         pygame.display.set_caption("我的游戏")
#         icon_surface = pygame.image.load("./image/favicon.ico")
#         pygame.display.set_icon(icon_surface)
#
#     def init_event(self):
#         for event in pygame.event.get():
#             if event.type == pygame.QUIT:
#                 pygame.quit()
#                 exit()
#
#     def update_draw(self):
#         # 绘制精灵组到一个面  并且更新精灵组
#         self.bg_group.draw(self.screen)
#         self.bg_group.update()
#
#         self.hero_group.draw(self.screen)
#         self.hero_group.update()
#
#         pygame.display.flip()
#
#     def run(self):
#         while True:
#             self.clock.tick(20)
#             self.init_event()
#             self.update_draw()
#
#
# game = Game()
# game.run()


# 使用精灵类流程
# 创建精灵类  __init__   update
# 创建精灵组
# 将精灵实例 加入精灵组
# 绘制精灵组到面
# 更新精灵组

SIZE = (800, 600)


class MusicManage:
    @staticmethod
    def play_bg_music():
        pygame.mixer.music.load("./music/bg.mp3")
        pygame.mixer.music.play(loops=True)

    @staticmethod
    def play_sound():
        sound = pygame.mixer.Sound("./music/sound.mp3")
        sound.play()

class UISprite(pygame.sprite.Sprite):
    def __init__(self, name, center):
        super().__init__()
        self.image = pygame.image.load(f"./image/{name}")
        self.rect = self.image.get_rect()
        self.rect.center = center




class Util:
    @staticmethod
    def check_click(spite):
        if pygame.mouse.get_pressed()[0]:
            mouse_pos = pygame.mouse.get_pos()
            return spite.rect.collidepoint(mouse_pos)




class UIManage:
    def __init__(self, gm):
        self.score = 0
        self.font = pygame.font.Font("./font/Inkfree.ttf", 24)
        self.score_label = self.font.render(f"Score: {self.score}", True, "red")
        self.gm = gm

        self.ready_group = pygame.sprite.Group()
        self.begin_btn = UISprite("begin_btn.png", (400, 300))
        self.begin_btn.add(self.ready_group)


        self.end_group = pygame.sprite.Group()
        self.restart_btn = UISprite("replay_btn.png", (400, 300))
        self.restart_btn.add(self.end_group)

    def add_score(self):
        self.score += 1
        self.score_label = self.font.render(f"Score: {self.score}", True, "red")

    def update(self):
        if self.gm.state == "ready":
            self.ready_group.draw(self.gm.screen)
            self.ready_group.update()

            if Util.check_click(self.begin_btn) and self.gm.state == "ready":
                self.gm.state = "gaming"

        if self.gm.state == "gaming":
            self.gm.screen.blit(self.score_label, (700, 20))

        if self.gm.state == "end":
            self.end_group.draw(self.gm.screen)
            self.end_group.update()

            if Util.check_click(self.restart_btn) and self.gm.state == "end":
                self.gm.state = "gaming"
                self.score = 0
                self.score_label = self.font.render(f"Score: {self.score}", True, "red")


class FoodSprite(pygame.sprite.Sprite):
    def __init__(self, left, top):
        super().__init__()
        self.image = pygame.surface.Surface((60, 60))
        pygame.draw.circle(self.image, (0, 125, 0), (30, 30), 30)
        self.rect = self.image.get_rect()
        self.rect.left = left
        self.rect.top = top


class FoodManage:
    def __init__(self, gm):
        self.food_group = pygame.sprite.Group()

        self.generate()
        self.gm = gm

    def generate(self):
        left = random.randint(0, 740)
        top = random.randint(0, 540)
        self.food1 = FoodSprite(left, top)
        self.food1.add(self.food_group)

    def update(self):
        if self.gm.state == "gaming":
            self.food_group.draw(self.gm.screen)
            self.food_group.update()


class BGSprite(pygame.sprite.Sprite):
    def __init__(self, name, pos_y, speed=5):
        super().__init__()
        self.image = pygame.image.load(f"./image/{name}")
        self.rect = self.image.get_rect()
        self.rect.top = pos_y
        self.speed = speed

    def update(self):
        self.rect.top += self.speed
        if self.rect.top >= SIZE[1]:
            # 需要注意 n就是总共有几个背景精灵
            n = 3
            self.rect.top = -SIZE[1] * (n - 1)


class HeroSprite(pygame.sprite.Sprite):
    def __init__(self, speed=20):
        super().__init__()
        self.image_left = pygame.image.load("./image/hero.jpeg")
        self.image_right = pygame.transform.flip(self.image_left, True, False)
        self.image = self.image_left
        self.rect = self.image.get_rect()
        self.rect.center = (SIZE[0] / 2, SIZE[1] - 100)
        self.speed = speed

    def update(self):
        key_pressed = pygame.key.get_pressed()
        if key_pressed[pygame.K_LEFT] or key_pressed[pygame.K_a]:
            if self.image is not self.image_left:
                self.image = self.image_left
            self.rect.left -= self.speed
            if self.rect.left <= 0:
                self.rect.left = 0
        if key_pressed[pygame.K_RIGHT] or key_pressed[pygame.K_d]:
            if self.image is not self.image_right:
                self.image = self.image_right
            self.rect.right += self.speed
            if self.rect.right >= SIZE[0]:
                self.rect.right = SIZE[0]
        if key_pressed[pygame.K_UP] or key_pressed[pygame.K_w]:
            self.rect.top -= self.speed
            if self.rect.top <= 0:
                self.rect.top = 0
        if key_pressed[pygame.K_DOWN] or key_pressed[pygame.K_s]:
            self.rect.bottom += self.speed
            if self.rect.bottom >= SIZE[1]:
                self.rect.bottom = SIZE[1]


class HeroManage:
    def __init__(self, gm):
        self.hero_group = pygame.sprite.Group()
        self.hero = HeroSprite()
        self.hero.add(self.hero_group)
        self.gm = gm

    def update(self):
        if self.gm.state == "gaming":
            self.hero_group.draw(self.gm.screen)
            self.hero_group.update()


class BGManage:
    def __init__(self, gm):
        self.bg_group = pygame.sprite.Group()

        self.bg1 = BGSprite("bg.png", 0)
        self.bg1.add(self.bg_group)
        self.bg2 = BGSprite("bg2.jpeg", -600)
        self.bg2.add(self.bg_group)
        self.bg3 = BGSprite("bg3.jpeg", -1200)
        self.bg3.add(self.bg_group)

        self.gm = gm

    def update(self):
        self.bg_group.draw(self.gm.screen)
        if self.gm.state == "gaming":
            self.bg_group.update()


class GameManage:
    def __init__(self):
        self.state = "ready"
        pygame.init()
        pygame.display.set_caption("我的游戏")
        logo = pygame.image.load("./image/favicon.ico")
        self.clock = pygame.time.Clock()
        pygame.display.set_icon(logo)
        self.screen = pygame.display.set_mode(size=SIZE)
        MusicManage.play_bg_music()

        self.bg_manage = BGManage(self)
        self.food_manage = FoodManage(self)
        self.hero_mange = HeroManage(self)
        self.ui_manage = UIManage(self)



    def check_event(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                exit()

            if event.type == pygame.KEYUP and self.state == "gaming":
                if event.key == pygame.K_k:
                    self.state = "end"



    def check_colloder(self):
        if self.state == "gaming":
            # r = pygame.sprite.groupcollide(self.hero_mange.hero_group, self.food_manage.food_group, False, False)
            # if r:
            #     for v in r.values():
            #         for f in v:
            #             f.kill()

            r = pygame.sprite.spritecollide(self.hero_mange.hero, self.food_manage.food_group, False)
            if r:
                for f in r:
                    print(f)
                    f.kill()
                    self.food_manage.generate()
                    self.ui_manage.add_score()
                    MusicManage.play_sound()
    def update_draw(self):
        self.bg_manage.update()
        self.food_manage.update()
        self.hero_mange.update()
        self.ui_manage.update()


        pygame.display.flip()

    def run(self):
        while True:
            self.clock.tick(20)
            self.check_event()
            self.check_colloder()
            self.update_draw()


gm = GameManage()
gm.run()
